package com.ppg.basic.lock;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class LockTest {

//    private static ExecutorService executorService = Executors.newFixedThreadPool(10);

    private static volatile Boolean flag = true;

    public static void main(String[] args) {

        ReentrantLock lock = new ReentrantLock();

        Condition condition = lock.newCondition();


        try {
            lock.lock();
            condition.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


        System.out.println("x");
//        Thread thread = new Thread(new Runnable() {
//            @Override
//            public void run() {
//                while (flag){
//
//                }
//                System.out.println(flag);
//            }
//        });
//        thread.start();
//
//        new MyThread().start();
//
//        System.out.println("main end...");
    }

    static class MyThread extends Thread {
        @Override
        public void run() {
            try {
                Thread.sleep(2000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            flag = false;
        }
    }

    public static void test() {
        ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
        //获取读锁
        reentrantReadWriteLock.readLock().lock();
        System.out.println("get readLock");
        //获取写锁
        reentrantReadWriteLock.writeLock().lock();
        System.out.println("get writeLock");

        //因为同一个线程中，在没有释放读锁的情况下，就去申请写锁，这属于锁升级，ReentrantReadWriteLock是不支持的
    }

    public static void test2() {
        ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();

        //获取写锁
        reentrantReadWriteLock.writeLock().lock();
        System.out.println("get writeLock");

        //获取读锁
        reentrantReadWriteLock.readLock().lock();
        System.out.println("get readLock");

        /**
         * ReentrantReadWriteLock支持锁降级，上面代码不会产生死锁。
         * 这段代码虽然不会导致死锁，但没有正确的释放锁。
         * 从写锁降级成读锁，并不会自动释放当前线程获取的写锁，仍然需要显示的释放，否则别的线程永远也获取不到写锁
         */
    }

    public static void readLock() {

        CyclicBarrier cyclicBarrier = new CyclicBarrier(10);

        for (int i = 0; i < 10; i++) {


            new Thread(() -> {

                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName());
            }).start();
        }
    }

    public static void test3() {

        new Thread(() -> {
            int i = 0;
            while (flag) {

                System.out.println(++i);
            }

            System.out.println("xxxxxxx");
        }).start();


        System.out.println("11");

//        flag = false;
//
//        try {
//            TimeUnit.SECONDS.sleep(5L);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//        System.out.println(" exit;");
    }
}
